package com.recordhistory.service;

import cn.hutool.core.io.file.FileReader;
import com.recordhistory.dao.HistoryImgDao;
import com.recordhistory.exception.ServiceException;
import com.recordhistory.model.HistoryImg;
import com.recordhistory.utils.CheckTool;
import com.recordhistory.utils.CommonTool;
import com.recordhistory.utils.FileTool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.List;

/**
 * @author ：LX
 * 创建时间： 2019/6/18. 10:09
 * 地点：广州
 * 目的: 历史地图
 * 备注说明：
 */
@Service
public class HistoryImgService {

    private static Logger log = LoggerFactory.getLogger(HistoryImgService.class);

    @Resource
    private HistoryImgDao historyImgDao;



    /**
     * 图片的基址
     * 默认读取的是application.properties
     */
    @Value("${base.img}")
    private String basePathImg;


    /**
     * 校验基础的图片信息数据是否完整
     * @param historyImg
     */
    private void checkHistoryImg(HistoryImg historyImg){
        if (historyImg == null){
            throw new ServiceException("请填写数据");
        }
        if (CheckTool.checkNull(historyImg.getEventOccurId())){
            throw new ServiceException("请与事件进行关联");
        }
        if (CheckTool.checkNull(basePathImg)){
            throw new ServiceException("未配置图片保存地址，请联系管理员");
        }
    }

    /**
     * 校验图片是否合格
     * @param prefix 图片后缀
     * @return true 合格 false 不合格
     */
    private boolean checkImg(String prefix){
        if ("jpg".equals(prefix) || "gif".equals(prefix) || "png".equals(prefix)){
            return true;
        }
        return false;
    }

    /**
     * 上传 图片到指定位置
     * @param multipartFile 图片文件
     * @return 图片的名字带后缀
     */
    private String uploadImg(MultipartFile multipartFile){
        String originalFilename = multipartFile.getOriginalFilename();
        if (CheckTool.checkNull(originalFilename)){
            throw new ServiceException("获取文件名失败");
        }
        //文件后缀
        String prefix = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);

        //转换为小写
        prefix = prefix.toLowerCase();
        if (!checkImg(prefix)){
            throw new ServiceException("图片格式错误，不支持的格式");
        }
        //图片名
        String imgName = CommonTool.getUUId() + "." + prefix;

        FileTool.multipartFileWriteFile(basePathImg + imgName, multipartFile);

        return imgName;
    }

    /**
     * 添加 历史图片
     * @param historyImg 图片data
     * @param multipartFile 图片
     */
    @Transactional(rollbackFor = Exception.class)
    public void addHistoryImg(HistoryImg historyImg, MultipartFile multipartFile){
        checkHistoryImg(historyImg);

        //处理上传文件
        if (multipartFile == null || multipartFile.getSize() == 0){
            throw new ServiceException("图片不能为空");
        }

        FileTool.init(basePathImg);
        String imgName = uploadImg(multipartFile);

        historyImg.setId(CommonTool.getUUId());
        historyImg.setCreateDate(CommonTool.getTimestamp());
        historyImg.setUpdateDate(CommonTool.getTimestamp());
        historyImg.setPath(imgName);

        historyImgDao.insert(historyImg);
    }

    /**
     * 更新 历史图片
     * @param historyImg 图片data
     * @param multipartFile 图片
     */
    @Transactional(rollbackFor = Exception.class)
    public void updHistoryImg(HistoryImg historyImg, MultipartFile multipartFile){
        checkHistoryImg(historyImg);

        if (CheckTool.checkNull(historyImg.getId())){
            throw new ServiceException("主键为空，不能执行更新");
        }

        //旧的图片名
        String oldPath = null;
        if (multipartFile == null || multipartFile.getSize() == 0){
            //不做处理

        } else {
            //替换图片。先上传，在替换
            String imgName = uploadImg(multipartFile);

            oldPath = historyImg.getPath();
            historyImg.setPath(imgName);
        }

        historyImg.setUpdateDate(CommonTool.getTimestamp());
        historyImgDao.updateById(historyImg);

        //删除旧的图片
        if (!CheckTool.checkNull(oldPath)){
            FileTool.delectFile(basePathImg + oldPath);
        }
    }

    /**
     * 删除 图片
     * @param id 历史图片主键
     */
    @Transactional(rollbackFor = Exception.class)
    public void delHistoryImg(String id){
        if (CheckTool.checkNull(id)){
            throw new ServiceException("主键不能为空");
        }

        HistoryImg historyImg = historyImgDao.selectById(id);
        if (historyImg != null){
            historyImgDao.deleteById(id);
            if (!CheckTool.checkNull(historyImg.getPath())){
                FileTool.delectFile(basePathImg + historyImg.getPath());
            }
        }
    }

    /**
     * 根据 事件ID查询图片
     * @param eventOccurId 事件ID
     * @return
     */
    public List<HistoryImg> selectByEventId(String eventOccurId) {
        return historyImgDao.selectImgByEventOccurId(eventOccurId);
    }

    /**
     * 读取硬盘图片回显工具类
     * @param id 图片path
     */
    public void imgRead(HttpServletResponse response, String id){
        if (CheckTool.checkNull(id)){
            log.error("图片读取失败，没有id");
            return;
        }

        FileInputStream fileInputStream = null;
        OutputStream out = null;
        try {
            fileInputStream = new FileInputStream(basePathImg + id);
            //获得文件大小
            int i = fileInputStream.available();
            byte data[] = new byte[i];
            //读取数据，通过文件输入流将数据都到byte中
            fileInputStream.read(data);
            //设置返回的文件类型
            response.setContentType("image/*");
            out = response.getOutputStream();
            out.write(data);
            //清空缓冲区
            out.flush();

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (out != null){
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fileInputStream != null){
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}
